package com.sharedlease.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.sharedlease.entity.Pay;
import com.sharedlease.utils.AlipayConfig;
import com.sharedlease.utils.AlipayUtil;
import com.sharedlease.utils.CodeUtil;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.sharedlease.utils.AlipayConfig.*;
import static com.sharedlease.utils.AlipayConstant.*;

/**
 * @author Laymedown
 */
@RestController
@Api(tags = "支付相关接口")
@RequestMapping("/pay")
public class PayController {

    @Autowired
    public JdbcTemplate jdbcTemplate;

    /**
     * 调用支付， 成功后会自动调用 notify 和 return 两个回调函数, 回调函数的 url 可在 AlipayConfig 中配置
     *
     * @param response
     * @return
     * @throws Exception
     */
    @GetMapping("/alipay/{uid}/{money}/{isShareProduct}")
    public String totalPay(HttpServletResponse response, @PathVariable String uid, @PathVariable String money,@PathVariable Integer isShareProduct) throws Exception {
        String subject = "支付宝支付";
        String totalAmount = money;
        String body = "阿里巴巴支付宝服务";
        response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        String out_trade_no = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + CodeUtil.getCode();
        System.out.println(out_trade_no);
        try {
            return AlipayUtil.pay(out_trade_no, subject, totalAmount, TIMEOUT_EXPRESS_MIDDLE, body, COMPUTER_PAY,isShareProduct);
        } catch (AlipayApiException e) {
            System.out.println(e.getErrMsg());
            return "fail";
        }
    }


    /**
     * 回调函数
     * 服务器异步调用（后台处理， 扣款）:
     *
     * @param request      :
     * @param out_trade_no : 商户订单号
     * @param trade_no     : 支付宝交易号
     * @param trade_status : 交易状态
     * @return
     */
    @RequestMapping("/notify")
    public String payNotify(HttpServletRequest request, String out_trade_no, String trade_no, String trade_status) {
        System.out.println("异步调用");
        Map<String, String> params = getParamsMap(request);
        boolean verify_result = false;
        try {
            verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGNTYPE);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        System.out.println(verify_result + "2");
        if (verify_result) {
            //注意 : 异步调用必须返回 success , 支付报会根据 success 判断
            return "success";
        } else {
            try {
                AlipayUtil.refund(out_trade_no, trade_no, params.get("invoice_amount"), "支付失败退款", CodeUtil.getCode().toString());
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            return ("fail");
        }
    }

    /**
     * 回调函数
     * 同步跳转(只返回是否支付成功， 不知扣款情况) : 用户支付后返回的页面，只验证是否成功并返回结果
     *
     * @param request      :
     * @param out_trade_no : 商户订单号
     * @param trade_no     : 支付宝交易号
     * @return
     */

    @RequestMapping("/return")
    public void payReturn(HttpServletRequest request, String out_trade_no, String trade_no, HttpServletResponse response) {
        Map<String, String> params = getParamsMap(request);
        System.out.println("retrun的param：" + params.toString());
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGNTYPE);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        System.out.println(signVerified + "1");
        String url;
        if (signVerified) {
            System.out.println("trade_no : " + trade_no);
            // 这里可返回数据给前端 （out_trade_no， trade_no）等等
//            req.setAttribute("out_trade_no",out_trade_no);
//            req.setAttribute("trade_no",trade_no);
//            req.setAttribute("trade_status","TRADE_SUCCESS");

            try {
//                req.getRequestDispatcher("http://42.193.131.89/dist/#/myOrders").forward(req, resp);
                url = "http://42.193.131.89/dist/#/myOrders?out_trade_no=" + out_trade_no + "&trade_no=" + trade_no + "&trade_status=" + "TRADE_SUCCESS";
                response.sendRedirect(url);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                url = "http://42.193.131.89/dist/#/myOrders?out_trade_no=" + out_trade_no + "&trade_no=" + trade_no + "&trade_status=" + "TRADE_FAIL";
                response.sendRedirect(url);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    @RequestMapping("/sharedReturn")
    public void sharedReturn(HttpServletRequest request, String out_trade_no, String trade_no, HttpServletResponse response) {
        Map<String, String> params = getParamsMap(request);
        System.out.println("进入sharedReturn");
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGNTYPE);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        System.out.println(signVerified + "1");
        String url;
        if (signVerified) {
            System.out.println("trade_no : " + trade_no);
            // 这里可返回数据给前端 （out_trade_no， trade_no）等等
//            req.setAttribute("out_trade_no",out_trade_no);
//            req.setAttribute("trade_no",trade_no);
//            req.setAttribute("trade_status","TRADE_SUCCESS");

            try {
//                req.getRequestDispatcher("http://42.193.131.89/dist/#/myOrders").forward(req, resp);
                url = "http://42.193.131.89/dist/#/successNotice?out_trade_no=" + out_trade_no + "&trade_no=" + trade_no + "&trade_status=" + "TRADE_SUCCESS";
                response.sendRedirect(url);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                url = "http://42.193.131.89/dist/#/successNotice?out_trade_no=" + out_trade_no + "&trade_no=" + trade_no + "&trade_status=" + "TRADE_FAIL";
                response.sendRedirect(url);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }


    }


    /**
     * //     * 退款 : 分为退全款 和 部分 退款， 如果退全款则不需要 out_request_no
     * //     * @param out_trade_no : 商户订单号
     * //     * @param trade_no : 支付宝交易号, trade_no 与 out_trade_no 不能同时为null
     * //     * @param refund_amount : 退款金额, 不能大于买入金额(前端传值时判断)
     * //     * @param refund_reason : 退款原因
     * //     * @param refundAll : 是否退全款 (1: 退全款， 0: 退部分)
     * //     * @return
     */
    @PostMapping("/refund/{out_trade_no}/{trade_no}/{refund_amount}")
    public String refund(@PathVariable String out_trade_no, @PathVariable String trade_no, @PathVariable String refund_amount, @RequestParam(defaultValue = "I do not want to write") String refund_reason) {
        String outRequestNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + CodeUtil.getCode();
        AlipayTradeRefundResponse response = null;
        try {
            response = AlipayUtil.refund(out_trade_no, trade_no, refund_amount, refund_reason, outRequestNo);
        } catch (AlipayApiException e) {
            System.out.println("退款出错");
        }

        if (response != null && response.isSuccess()) {
            String sql = "update indent set trade_status='TRADE_REFUND' where out_trade_no='" + out_trade_no + "'";
            jdbcTemplate.execute(sql);
            // 退款成功 ，返回成功数据
            // 这里可以将 out_request_no等数据存入数据库， 可供后面 退单查询使用
            return "success";
        } else {
            // 退款失败， 返回失败数据
            return "fail";
        }

    }
//
//    @RequestMapping("/query")
//    public Pay query(@RequestParam String out_trade_no,@RequestParam String trade_no){
//        /**
//         * 参数 ： String out_trade_no, String trade_no
//         */
//
//
//        AlipayTradeQueryResponse response = null;
//        try {
//            response = AlipayUtil.query(out_trade_no, trade_no);
//        } catch (AlipayApiException e) {
//            e.printStackTrace();
//        }
//
//        if (response !=null){
//            return new W;
//            // 返回 response 中的数据， 需根据实际情况指定返回数据
//        }else{
//            // 返回查询错误
//        }
//        return null;
//    }

//    @RequestMapping("/refundquery")
//    public String refundQuery(){
//        /**
//         * 参数 : String out_trade_no, String trade_no, String out_request_no
//         */
//        String out_trade_no = "";
//        String trade_no = "";
//        String out_request_no = "";
//        AlipayTradeFastpayRefundQueryResponse response = null;
//        try {
//            response = AlipayUtil.refundQuery(out_trade_no, trade_no, out_request_no);
//        } catch (AlipayApiException e) {
//            e.printStackTrace();
//        }
//
//        if (response !=null){
//            // 返回 response 中的数据， 需根据实际情况指定返回数据
//        }else{
//            // 返回查询错误
//        }
//        return null;
//    }
//


    private Map<String, String> getParamsMap(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Object o : requestParams.keySet()) {
            String name = (String) o;
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
//            valueStr = new String(valueStr.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            params.put(name, valueStr);
        }
        return params;
    }
}
